<?php

namespace Biz\Services\User;

use Lumen\Logger\Logger;
use Illuminate\Http\Request;
use Biz\Models\User\UserMember;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Biz\Constants\User\UserConstants;
use Biz\Criteria\Site\SiteFilterCriterion;
use Biz\Criteria\Site\UserFilterCriterion;
use Lumen\Core\Contracts\ExceptionContract;
use Lumen\Core\Exceptions\BusinessException;
use Illuminate\Contracts\Pagination\Paginator;
use Biz\Repositories\User\UserMemberRepository;

/**
 * UserMemberService.
 *
 * @license [http://www.85do.com] [杭州永奥网络科技有限公司]
 * @copyright Copyright (c) 2018-2026 Hangzhou Yongao Technology Co., Ltd. All rights reserved.
 */
class UserMemberService
{
    /**
     * @var UserMemberRepository
     */
    protected $repository;

    /**
     * @var UserService
     */
    protected $userService;

    /**
     * RepositoryController constructor.
     *
     * @param UserMemberRepository $repository
     * @param UserService          $userService
     */
    public function __construct(UserMemberRepository $repository, UserService $userService)
    {
        $this->repository  = $repository;
        $this->userService = $userService;
    }

    /**
     * 列表页.
     *
     * @param Request $request
     *
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|mixed
     */
    public function index(Request $request): Paginator
    {
        $site_id  = $request->get('site_id');
        $pageSize = $request->get('page_size', 10);

        $results = $this->repository
            ->with(['user'])
            ->setCacheLifetime(0)
            ->pushCriterion(new SiteFilterCriterion($site_id))
            //->pushCriterion(new LocaleFilterCriterion())
            ->paginate($pageSize);

        return $results;
    }

    /**
     * Find.
     *
     * @param $id
     *
     * @throws BusinessException
     *
     * @return \Biz\Models\User\UserMember
     */
    public function find($id): UserMember
    {
        $userMember = $this->repository->find($id);
        if (is_null($userMember)) {
            throw new BusinessException(trans('user.member_not_found'));
        }

        return $userMember;
    }

    /**
     * Find By User Id.
     *
     * @param int $userId
     *
     * @throws BusinessException
     *
     * @return \Biz\Models\User\UserMember
     */
    public function findByUserId(int $userId): UserMember
    {
        $userMember = $this->repository
            ->pushCriterion(new UserFilterCriterion($userId))
            ->findFirst();
        if (is_null($userMember)) {
            throw new BusinessException(trans('user.member_not_found'));
        }

        return $userMember;
    }

    /**
     * Store a new client.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return UserMember
     */
    public function store(Request $request): UserMember
    {
        $data = $request->all();

        return $this->create($data);
    }

    /**
     * Create.
     *
     * @param array $data
     *
     * @throws \Exception
     * @throws ExceptionContract
     *
     * @return UserMember
     */
    public function create(array $data): UserMember
    {
        // 1) Start Transaction
        DB::beginTransaction();
        try {
            // 创建用户
            $data['type'] = UserConstants::TYPE_MEMBER;
            $user         = $this->userService->create($data);

            // 创建成员
            $data['user_id']            = $user->id;
            $allowField                 = $this->repository->createModel()->getFillable();
            $allowData                  = array_only($data, $allowField);
            /** @var UserMember $userMember */
            $userMember = $this->repository->create($allowData);
            if (! $userMember) {
                throw new BusinessException(trans('user.member_create_fail'));
            }

            $userMember->setUser($user);

            // 2) Commit Transaction
            DB::commit();
        } catch (\Exception $e) {
            // 3) Rollback Transaction
            DB::rollback();
            // 4) Log Transaction
            Logger::error(__CLASS__, __FUNCTION__, $e);
            // 5) Throw Exception
            throw $e;
        }

        return $userMember;
    }

    /**
     * Profile.
     *
     * @param Request $request
     *
     * @throws \Exception
     * @throws ExceptionContract
     *
     * @return UserMember
     */
    public function profile(Request $request): UserMember
    {
        $data = $request->all();
        $user = $request->user();

        $userMember = $this->findByUserId($user->id);

        return $this->repository->update($userMember, $data);
    }

    /**
     * Login.
     *
     * @param array $data
     *
     * @throws \Exception
     * @throws BusinessException
     *
     * @return UserMember
     */
    public function login(array $data): UserMember
    {
        $user       = $this->userService->login($data);

        if (! $user->isMember()) {
            throw new BusinessException(trans('user.member_not_found'));
        }

        $userMember = $user->member()->first();

        if (is_null($userMember)) {
            throw new BusinessException(trans('user.member_not_found'));
        }

        $userMember->setUser($user);

        return $userMember;
    }
}
